package com.ankiang.treeprint.model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ankiang.treeprint.fragment.util.TRUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class TRItemTree implements Map<Integer, TRItemNode> {

    private static final String TAG = "TRItemTree";

    private static final int MAX_COLUMN_SIZE = 500; // 最多200代，所以列数也最多200
    private static final int MAX_ROW_SIZE = 500;
    private String err;


    private int mNodeWidth = 164;
    private int mNodeHeight = 196;
    private int mNodeLeftMargin = 232;
    private int mNodeTopMargin = 232;

    public int getGroupId() {
        return groupId;
    }

    public void setGroupId(int groupId) {
        this.groupId = groupId;
    }

    int groupId = -1;

    int maxRight = -1;
    int maxBottom = -1;

    public int getMaxRight() {
        return maxRight;
    }

    public int getMaxBottom() {
        return maxBottom;
    }

    public static TRItemTree convert(JSONArray list) {
        TRItemTree tree = new TRItemTree();
        if (list == null) {
            LOG.jLoge("TRItemTree.convert error: list=null");
            return tree;
        }
        for (int i = 0; i < list.size(); i++) {
            try {
                JSONObject obj = list.getJSONObject(i);
                TRItemNode item = TRItemNode.convert(obj);
                tree.addItem(item);
            } catch (Exception e) {
                LOG.jLoge("读取数据错误: %s", e.getMessage());
                continue;
            }
        }
        return tree;
    }


    public TRItemTree() {
        itemChildren = new HashMap<>();
        mColumnMap = new HashMap<>();
        itemMap = new HashMap<>();
        mColumnSize = 1;
        mRowSize = 1;
        this.err = null;
    }


    public Set getChildren(int id) {
        Set<Integer> res = this.itemChildren.get(id);
        if (res == null) {
            return new HashSet();
        }
        return res;
    }

    // 检索数据的字典
    private HashMap<Integer, TRItemNode> itemMap;
    HashMap<Integer, ArrayList> mColumnMap;

    // 直系子节点
    HashMap<Integer, Set<Integer>> itemChildren;

    private int mColumnSize;
    private int mRowSize;


    public void addItem(TRItemNode itemNode) {
        if (itemMap == null) {
            itemMap = new HashMap<>();
        }
        int id = itemNode.getId();

        itemMap.put(id, itemNode);

    }

    public void addItem(int id, int fid, int mid, String nickname, char sex) {
        TRItemNode item = new TRItemNode();
        item.setNickname(nickname);
        item.setCallname(nickname);
        item.setName(nickname);
        item.setId(id);
        item.setMid(mid);
        item.setFid(fid);
        item.setSex(sex);
        item.setRow(0);
        item.setColumn(0);
        item.setColor(0);
        item.setBornDateSun("2018-01-02");
        item.setBornDateMoon("2017-12-12");
        addItem(item);

    }

    public void calcColumnAndRow() {
        this.err = null;

        // 初始化行列数据
        initColumnAndRow();


        // 计算出各列
        calcColumn();

        // 根据列计算出节点的水平位置
        initLeft();

        // 初始化列列表，即每列有哪些节点
        initColumnMap();

        // 行排序
        makeRowSorted();

        // 根据行计算出节点的垂直位置
        initTop();


        // 根据父辈进行排序：将子辈调整到一起
        layoutRowWithParent();

        // 根据子辈进行调整：父辈在子辈们的中间位置
        layoutRowWithSub();

        // 计算出行位置来
//        calcRow();

        // 收缩空白的行和列
        layoutTrimRowAndColumn();
    }

    private void initTop() {

        Iterator<TRItemNode> iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            calcTopByRow(item);
        }
    }

    /**
     * 根据列计算出水平位置
     */
    private void initLeft() {
        Iterator<TRItemNode> iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            calcLeftByColumn(item);
        }
    }

    public String getErr() {
        return err;
    }

    /**
     * 计算列
     * <p>
     * 算法：
     * 从子节点出发，不断追溯父节点
     * 树的最长深度，就是列的数量
     */
    public void calcColumn() {

        HashMap m = new HashMap();
        Iterator<TRItemNode> iter = this.values().iterator();
        iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue;
            }
            m.put(item.getId(), item);
        }
        // 遍历
        // 防止死循环，加了一个限制
        // 如果存在环时，也可能出现死循环
        HashMap mHasPid = new HashMap();

        while (!m.isEmpty() && mColumnSize < this.size() + 10) { // 列不可能超过总数
            // 从子节点开始，逐层计算列
            iter = m.values().iterator();
            while (iter.hasNext()) {
                TRItemNode item = iter.next();
                if (m.containsKey(item.getFid()) || m.containsKey(item.getMid())) {
                    item.setColumn(mColumnSize);
                    mHasPid.put(item.getId(), item); // 有父节点的，需要继续处理
//                    item.setColor(1); // 设置为已染色
                    // 这里同一个节点会更新多次，不能只更新一次
                    // todo 不能在遍历的过程进行修改！！！
                    //this.put(item.getId(), item);
                }
            }
            mColumnSize += 1;
            if (mColumnSize > this.size() + 1) {
                List<String> tmpList = new ArrayList<>();
                iter = m.values().iterator();
                while (iter.hasNext()) {
                    TRItemNode tmp = iter.next();
                    String s = String.format("%d:%s", tmp.getId(), tmp.getCallname());
                    tmpList.add(s);
                }

                this.err = String.format("发现了环，请纠正, id = { %s }",
                        TRUtils.myJoin(", ", tmpList));

            }
//            LOG.jLogd("cal column, mColumnSize = %d", mColumnSize);

            // 将mHasPid放到m里
            m.clear();
            m.putAll(mHasPid);
            mHasPid.clear();
        }

        // 如果父节点没有，且有子节点，则column=以子节点column-1的
        iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) { // 有出现过为null的情况
                continue;
            }
            if (item.getColumn() == -1) { // 如果存在没有处理的节点，设置为0
                item.setColumn(0);
            }
            item.setColumn(item.getColumn() % mColumnSize);

            calcLeftByColumn(item);

            // todo 不能在遍历的过程进行修改！！！
            //this.put(item.getId(), item);
        }

        boolean isOver = false;
        for (int k = 0; k < this.values().size() / 2 && !isOver; k++) {
            isOver = true;
            // 确保父子节点之间的column最多相差1
            boolean isDone = false;
            for (int i = 0; i < this.values().size() && !isDone; i++) { // 控制最多循环的次数
                isDone = true;

                // 找到
                iter = this.values().iterator();
                while (iter.hasNext()) {
                    TRItemNode item = iter.next();
                    TRItemNode pItem;
                    if (hasFather(item)) {
                        pItem = getFather(item);
                        if (item.getColumn() - pItem.getColumn() > 1) {
                            pItem.setColumn(item.getColumn() - 1);
                            isDone = false;
                            isOver = false;
                        }
                    }

                    if (hasMother(item)) {
                        pItem = getMother(item);
                        if (item.getColumn() - pItem.getColumn() > 1) {
                            pItem.setColumn(item.getColumn() - 1);
                            isDone = false;
                            isOver = false;
                        }
                    }
                }

            }
            // 确保父子节点之间的column不是一样的
            isDone = false;
            for (int i = 0; i < this.values().size() && !isDone; i++) { // 控制最多循环的次数
                isDone = true;

                // 找到
                iter = this.values().iterator();
                while (iter.hasNext()) {
                    TRItemNode item = iter.next();
                    TRItemNode pItem;
                    int maxCol = item.getColumn() - 1;
                    if (hasFather(item)) {
                        pItem = getFather(item);
                        if (pItem.getColumn() > maxCol) {
                            maxCol = pItem.getColumn();
                            isDone = false;
                            isOver = false;
                        }
                    }

                    if (hasMother(item)) {
                        pItem = getMother(item);
                        if (pItem.getColumn() > maxCol) {
                            maxCol = pItem.getColumn();
                            isDone = false;
                            isOver = false;
                        }
                    }
                    item.setColumn(maxCol + 1);
                }

            }
        }

        // 找到最大的column作为columnSize
        int maxColumn = 0;
        iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue; // todo 这里出现过为null的情况，原因不明
            }
            if (maxColumn < item.getColumn()) {
                maxColumn = item.getColumn();
            }
        }
        mColumnSize = maxColumn + 1;
        // 这里提示一下
        LOG.jLogd("mColumnSize: %d", mColumnSize);
    }


    /**
     * 根据列计算位置
     *
     * @param item
     */
    private void calcLeftByColumn(TRItemNode item) {

        // 计算
        item.setLeft( item.getColumn() * mNodeWidth);
        if(item.getColumn()!=0) {
            item.setLeft(item.getLeft() + (item.getColumn() - 1) * mNodeLeftMargin);
        }
//        if (item.getColumn() != 1) { // 不是第一个就要加列的距离
//        }

//        item.right = item.getLeft() + mNodeWidth;
    }

    /**
     * 根据行计算位置
     *
     * @param item
     */
    private void calcTopByRow(TRItemNode item) {

        item.setTop(item.getRow() * mNodeHeight);
        // 计算
        item.setTop(item.getTop() + item.getRow() * mNodeTopMargin);
//        if (item.getRow() != 0) { // 不是第一个就要加列的距离
//        }
//        item.bottom = item.getTop() + mNodeHeight;
    }

    void initColumnAndRow() {
        mColumnSize = 1;
        mRowSize = 0;

        // 全部column设置为-1，必须初如化为-1
        Iterator<TRItemNode> iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null || item.getId() == 0) { // 这里为啥还可能是null? 反正就是出现过
                continue;
            }
            item.setColor(0);
            item.setColumn(-1);
            item.setRow(-1);


            // 添加子节点集合
            if (hasFather(item)) {
                int tid = item.getFid();
                if (!itemChildren.containsKey(tid)) {
                    itemChildren.put(tid, new HashSet<Integer>());
                }
                itemChildren.get(tid).add(item.getId());
            }
            if (hasMother(item)) {
                int tid = item.getMid();
                if (!itemChildren.containsKey(tid)) {
                    itemChildren.put(tid, new HashSet<Integer>());
                }
                itemChildren.get(tid).add(item.getId());
            }
        }

    }


    private void initColumnMap() {

        Iterator<TRItemNode> iter = this.values().iterator();

        // 遍历
        mColumnMap = new HashMap();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue;
            }
            if (!mColumnMap.containsKey(item.getColumn())) {
                mColumnMap.put(item.getColumn(), new ArrayList());
            }
            mColumnMap.get(item.getColumn()).add(item);
        }

    }

    private void makeRowSorted() {

        for (int i = 0; i < mColumnSize; i++) {
            if (!mColumnMap.containsKey(i)) {
                continue;
            }
            ArrayList<TRItemNode> list = mColumnMap.get(i);

            // 1. 先按父辈排序，按排行排序
            Collections.sort(list, (o1, o2) -> {
                TRItemNode a = (TRItemNode) o1;
                TRItemNode b = (TRItemNode) o2;
                if (a == b) {
                    return 0;
                }
                if (a == null) {
                    return -1;
                }
                if (b == null) {
                    return 1;
                }

                int aRow = 0;
                int bRow = 0;

                if (hasFather(a)) {
                    aRow = getFather(a).getRow();
                } else if (hasMother(a)) {
                    aRow = getMother(a).getRow();
                }

                if (hasFather(b)) {
                    bRow = getFather(b).getRow();
                } else if (hasMother(b)) {
                    bRow = getMother(b).getRow();
                }

                // 如果一方只有母辈，另一方有父母辈
                if (!hasFather(a) && hasMother(a) && hasFatherAndMother(b)) {
                    aRow = getMother(a).getRow();
                    bRow = getMother(b).getRow();
                } else if (!hasFather(b) && hasMother(b) && hasFatherAndMother(b)) {
                    aRow = getMother(a).getRow();
                    bRow = getMother(b).getRow();
                }

                // 此时父辈已经排序，用父辈的row进行排序
                if (aRow != bRow) {
                    return aRow - bRow;
                }

//                if (b.getFid() != a.getFid()) {
//                    if (hasFather(a) && hasFather(b)) {
//                        return getFather(a).getRow() - getFather(b).getRow();
//                    }
//                    return a.getFid() - b.getFid();
//                }
//                if (b.getMid() != a.getMid()) {
//                    if (hasMother(a) && hasMother(b)) {
//                        return getMother(a).getRow() - getMother(b).getRow();
//                    }
//                    return a.getMid() - b.getMid();
//                }
                // 如果一方只有父辈，一方只有母辈


                if (b.getOrder() != a.getOrder()) {
                    return a.getOrder() - b.getOrder();
                }
                return 0;
            });

            // 2. 将所有没有父母辈的放到列表后面
            ArrayList<TRItemNode> tmp = new ArrayList<>();
            ArrayList<TRItemNode> noParent = new ArrayList<>();
            for (int k = 0; k < list.size(); k++) {
                TRItemNode item = list.get(k);
                if (!this.hasFatherOrMother(item)) {
                    noParent.add(item);
                    continue; // 有父母的不处理
                }
                tmp.add(item);
            }
            // tmp 有父母的
            // noParent 无父母的

            tmp.addAll(noParent);
            list = tmp;


            // ----------------------------------------
            // 3. 将没有父辈的，与相同子辈的另一半放一起

            // 遍历有父母的，从无父母的那拨中取出同子辈的放在一起
            for (int k = 0; k < list.size(); k++) {
                TRItemNode item = list.get(k);

                // 取得另一半
                Set<Integer> aSet = itemChildren.get(item.getId());
                if (aSet == null || aSet.isEmpty()) {
                    continue; // 没有子辈
                }
                // 取出一个子辈
                Iterator<Integer> iter = aSet.iterator();
                int aId = iter.next();// 只处理一个就结束


                TRItemNode aItem = this.get(aId);
                if (aItem == null) { // 节点不存在
                    continue;
                }

                // 判断本节点是子节点的父还是母
                int xId = aItem.getFid();
                boolean isFather = true;
                if (item.getId() == xId) { // 如果不是子节点的父节点，那么就是母节点
                    xId = aItem.getMid();
                    isFather = false;
                }

                aItem = this.get(xId);
                if (aItem != null && hasFatherOrMother(aItem)) {
                    continue;// 如果另一半有父母，就不移动了
                }

                // 把xId从原来的位置挪到item旁边
                // 母节点在下方
                for (int j = list.size() - 1; j >= 0; j--) {
                    aItem = list.get(j);
                    if (aItem.getId() == xId) {
                        TRItemNode xItem = list.remove(j);
                        if (isFather && k != 0) {
                            list.add(k, xItem);
                        } else if (k + 1 < list.size()) {
                            list.add(k + 1, xItem);
                        } else {
                            list.add(xItem);
                        }
                        k++;

                        break;
                    }
                }

            }


            // 初始化行
            for (int k = 0; k < list.size(); k++) {
                TRItemNode item = list.get(k);
                item.setRow(k);
            }

            //

            // 对结合那一列进行父辈的排列
            if (hasFatherAndMother(list.get(0))) {
//            if (i % 2 == 1) {
                Collections.sort(list, (o1, o2) -> {

                    // 如果不是同时有父辈和母辈，就直接返回原来的排序
                    if (!(hasFatherAndMother(o1) && hasFatherAndMother(o2))) {
                        return o1.getRow() - o2.getRow();
                    }
                    int f1 = o1.getFid();
                    int f2 = o2.getFid();
                    TRItemNode item1 = get(f1);
                    TRItemNode item2 = get(f2);
                    if (item1 == item2) {
                        return 0;
                    }
                    if (item1 == null) {
                        return -1;
                    }
                    if (item2 == null) {
                        return 1;
                    }
                    return item1.getRow() - item2.getRow();
                });

                // 重设行
                for (int k = 0; k < list.size(); k++) {
                    TRItemNode item = list.get(k);
                    item.setRow(k);
                }
            }


            // 更新
            mColumnMap.put(i, list);

        }

    }


    private void layoutTrimRowAndColumn() {

        // 找到最小的行
        int minTop = -1;
        int minLeft = -1;
        maxRight = 0;
        maxBottom = 0;
        Iterator<TRItemNode> iter = itemMap.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue;
            }
            if (minTop == -1) {
                minTop = item.getTop();
            }
            if (minLeft == -1) {
                minLeft = item.getLeft();
            }
            if (maxRight == -1) {
                maxRight = item.getRight();
            }
            if (maxBottom == -1) {
                maxBottom = item.getBottom();
            }

            if (item.getLeft() < minLeft) {
                minLeft = item.getLeft();
            }
            if (item.getTop() < minTop) {
                minTop = item.getTop();
            }
            if (item.getLeft() > maxRight) {
                maxRight = item.getLeft();
            }
            if (item.getTop() > maxBottom) {
                maxBottom = item.getTop();
            }

        }

        iter = itemMap.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue;
            }
            item.setLeft( item.getLeft() - minLeft);
            item.setTop(item.getTop() - minTop);


            // todo 不能在遍历的过程进行修改！！！
            //itemMap.put(item.getId(), item);
        }
        mRowSize -= minTop;

        // trim之后要把大小改了
        maxRight -= minLeft + mNodeWidth;
        maxBottom -= minTop + mNodeHeight;


    }

    /**
     * 调整有父母的行位置
     * 算法：
     * 将自己调整到父母的中间位置
     * 如果只有一方，调整到与自己相同的地方
     */
    private void layoutRowWithParent() {

        // 调整有父母的row
        for (int i = 0; i < mColumnSize; i++) {
            if (!mColumnMap.containsKey(i)) {
                continue;
            }
            ArrayList a = mColumnMap.get(i);

            for (int j = 0; j < a.size(); j++) {
                TRItemNode item = (TRItemNode) a.get(j);
                item = this.get(item.getId()); // 确保这个用的是原始的数据
                if (hasFatherAndMother(item)) {

                    TRItemNode fNode = this.get(item.getFid());
                    TRItemNode mNode = this.get(item.getMid());
                    int childRow;

                    // 如果父辈是在一起，就调整
//                    if (Math.abs(fNode.getRow() - mNode.getRow()) == 1) {
//                        // 行数在前的不变, 行数在后的下移
//                        if (fNode.getRow() < mNode.getRow()) {
//                            // 调整row大的
//                            this.moveDownRow(mNode.getColumn(), mNode.getRow(), 1);
//                        } else {
//                            this.moveDownRow(fNode.getColumn(), fNode.getRow(), 1);
//                        }
//
//                    }

                    // 自己要调整到父辈和母辈的中间
                    childRow = (mNode.getTop() + fNode.getTop()) / 2;


                    if (childRow > item.getTop()) {
                        this.moveDownRow(item.getColumn(), item.getTop(), childRow - item.getTop());// 自己取下一行
                    }

                } else {
                    TRItemNode node = item;
                    if (hasFather(item)) {
                        node = this.get(item.getFid());
                    } else if (hasMother(item)) {
                        node = this.get(item.getMid());
                    }
                    if (node == null) { // 数据异常时，就继续
                        continue;
                    }

                    // 自己要调整到父母辈的中间位置
                    Set<Integer> children = itemChildren.get(node.getId());
                    if (children == null) {
                        continue;
                    }
                    Iterator<Integer> iter = children.iterator();
                    int max = 0;
                    int min = node.getTop();
                    while (iter.hasNext()) {
                        int id = iter.next();
                        if (item == null) {
                            continue;
                        }
                        TRItemNode aNode = get(id);
                        if (aNode == null) { // 如果已经删除，但节点ID还在
                            continue;
                        }
                        if (max < aNode.getTop()) {
                            max = aNode.getTop();
                        }
                        if (min > aNode.getTop()) {
                            min = aNode.getTop();
                        }
                    }
                    int childTop = node.getTop();

                    // node为父节点，item为本节点


//                    int childRow = (max+min)/2;
//
                    if (childTop > item.getTop()) {
                        this.moveDownRow(item.getColumn(), item.getTop(), childTop - item.getTop());// 自己取下一行
                    }

                }

            }
        }

    }

    private void layoutRowWithSub() {

        // 调整有子辈的row
        // 如果比子辈小，用子辈的
        // 如果父母都有，则以行数大的为准
        // 从最后一列开始
        for (int i = mColumnSize - 1; i >= 0; i--) {
            if (!mColumnMap.containsKey(i)) {
                continue;
            }
            ArrayList<TRItemNode> a = mColumnMap.get(i);
            // 第一列column=0
//            if (!hasFatherAndMother(a.get(0)) && a.get(0).getColumn() != 0) { // 不是结合节点且不是第一列那一列不处理
//                continue;
//            }

            for (int j = 0; j < a.size(); j++) {
                TRItemNode item = a.get(j);
                item = this.get(item.getId()); // 确保这个用的是原始的数据
                if (item == null) { // 数据异常时，会没有数据
                    continue;
                }
                Set<Integer> sons = getChildren(item.getId());
                if (sons.size() < 1) {
                    continue;
                } else if (sons.size() == 1) {//一个子节点，且子节点是有父母的情况
                    int tmp = sons.iterator().next();
                    TRItemNode tmpNode = get(tmp);
                    if (tmpNode != null && hasFatherAndMother(tmpNode)) {
                        continue;
                    }
                }

                int maxRow = -1;
                int minRow = -1;

                // 找出子节点最大和最小的
                Iterator<Integer> iter = sons.iterator();
                while (iter.hasNext()) {
                    int tmp = iter.next();
                    TRItemNode tmpItem = get(tmp);
                    if (tmpItem == null) {
                        continue;
                    }
                    if (maxRow == -1) {
                        maxRow = tmpItem.getTop();
                        minRow = tmpItem.getTop();
                        continue;
                    }

                    if (tmpItem.getTop() > maxRow) {
                        maxRow = tmpItem.getTop();
                    }
                    if (tmpItem.getTop() < minRow) {
                        minRow = tmpItem.getTop();
                    }
                }

                // 将自己移动到中间位置
                int mid = (maxRow + minRow) / 2;
                if (item.getTop() >= mid) {
                    continue;
                }
                int gap = mid - item.getTop();
                moveDownRow(i, item.getTop(), gap);

                // 将自己的父辈们都跟着移动
                if (hasFatherAndMother(item)) {
                    int tmpFatherRow = getFather(item).getTop();
                    int tmpMotherRow = getMother(item).getTop();
                    if (tmpFatherRow > tmpMotherRow) {
                        tmpFatherRow = tmpMotherRow;
                    }
                    moveDownRow(i - 1, tmpFatherRow, gap);
                } else if (hasFather(item)) {
                    int tmpRow = getFather(item).getTop();
                    moveDownRow(i - 1, tmpRow, gap);
                } else if (hasMother(item)) {
                    int tmpRow = getMother(item).getTop();
                    moveDownRow(i - 1, tmpRow, gap);
                }


            }
        }

    }

    public TRItemNode getFather(TRItemNode item) {
        return this.get(item.getFid());
    }

    public TRItemNode getMother(TRItemNode item) {
        return this.get(item.getMid());
    }

    /**
     * @param column
     * @param row    将row往下移step个
     * @param step
     * @return
     */
    private void moveDownRow(int column, int row, int step) {

        if (step <= 0) {
            LOG.jLoge("moveDownRow: step(%d) <= 0", step);
            return;
        }
        // 遍历所有，找到指定的column
        Iterator<TRItemNode> iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue;
            }
            // 指定column，且行大于或等于指定的row
            if (item.getColumn() == column && item.getTop() >= row) {
                item.setTop(item.getTop() + step);
                // todo 不能在遍历的过程进行修改！！！
//                this.put(item.getId(), item);
            }
        }

    }


    @Override
    public int size() {
        return this.itemMap.size();
    }

    @Override
    public boolean isEmpty() {
        return this.itemMap.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return this.itemMap.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return this.itemMap.containsValue(value);
    }


    @Override
    public TRItemNode get(Object key) {
        return this.itemMap.get(key);
    }


    @Override
    public TRItemNode put(Integer key, TRItemNode value) {
        return this.itemMap.put(key, value);
    }


    @Override
    public TRItemNode remove(Object key) {
        return this.itemMap.remove(key);
    }

    @Override
    public void putAll(Map<? extends Integer, ? extends TRItemNode> m) {
        this.itemMap.putAll(m);
    }

    @Override
    public void clear() {
        this.itemMap.clear();
    }


    @Override
    public Set<Integer> keySet() {
        return this.itemMap.keySet();
    }


    @Override
    public Collection<TRItemNode> values() {
        return this.itemMap.values();
    }


    @Override
    public Set<Entry<Integer, TRItemNode>> entrySet() {
        if (this.itemMap == null) {
            return new HashSet<>();
        }
        return this.itemMap.entrySet();
    }

    public int getColumnCount() {
        return mColumnSize;
    }

    public int getRowCount() {
        return mRowSize;
    }

    public void put(Integer i, JSONObject obj) {
        TRItemNode node = JSON.parseObject(obj.toJSONString(), TRItemNode.class);
        this.put(i, node);
    }


    public boolean hasMother(TRItemNode item) {
        if (item == null) {
            return false;
        }
        return itemMap.containsKey(item.getMid());
    }

    public boolean hasFather(TRItemNode item) {
        if (item == null) {
            return false;
        }
        return itemMap.containsKey(item.getFid());
    }

    public boolean hasFatherAndMother(TRItemNode item) {
        return hasFather(item) && hasMother(item);
    }

    public boolean hasFatherOrMother(TRItemNode item) {
        return hasFather(item) || hasMother(item);
    }

    /**
     * 取最大的ID再加1
     *
     * @return
     */
    public int getNextId() {
        int id = 0;
        // 遍历所有，找到指定的column
        Iterator<TRItemNode> iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue;
            }
            // 指定column，且行大于或等于指定的row
            if (id < item.getId()) {
                id = item.getId();
            }
        }
        return id + 1;
    }

    public JSONArray toJSONArray() {

        JSONArray arr = new JSONArray();

        // 遍历所有
        Iterator<TRItemNode> iter = this.values().iterator();
        while (iter.hasNext()) {
            TRItemNode item = iter.next();
            if (item == null) {
                continue;
            }
            arr.add(item);
        }
        return arr;
    }

    /**
     * 刷新结合名称
     *
     * @param item
     */
    public void refreshCoupleName(TRItemNode item) {
        if (item != null && item.getSex() == TRItemNode.Sex.COUPLE
                && hasFatherAndMother(item)) {
            String s = String.format("%s+%s", getFather(item), getMother(item));
            item.setCallname(s);
            return;
        }
    }

    public void setNodeHeight(int height) {
        this.mNodeHeight = height;
    }

    public void setNodeWidth(int width) {
        this.mNodeWidth = width;
    }

    public void setNodeLeftMargin(int x) {
        this.mNodeLeftMargin = x;
    }

    public void setNodeTopMargin(int x) {
        this.mNodeTopMargin = x;
    }
}
